﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta name="generator" content=
        "HTML Tidy, see www.w3.org" />

        <title>Indicators test page</title>
<script type="text/javascript">
 /* calculate and cache technical indicators data */
    
    function indicatorCalculation() {
        this.cachedData= {mfiData:{},vaccData:{},obvData:{},udData:{},smaData:{},emaData:{},bBandsData:{},macdData: {},rsiData:{},slowStochasticData:{},fastStochasticData:{},rocData:{},willRData:{},pSAR:{}};
    }
    
    indicatorCalculation.prototype = {
        filtrateCalculatedData: function(stIndex,endIndex,isFilled,aData,ty) {
            if (aData == null || aData.length<1) {
                return null;
            }
            var data  = [];
            var st = aData[0][aData[0].length-1], end = aData[aData.length-1][aData[aData.length-1].length-1];
            var interVal = 1;
            if (ty == 0 || ty == 1) { 
                interVal = 1;
            } else if (ty == 2) {
                interVal = 7;
            } else if (ty == 3) {
                interVal = 30;
            }
            var inx = 0;
            if (isFilled && stIndex < st) {   
                for (var i = stIndex; i < st; i += interVal) {
                     var dp = [inx,NaN,i];
                     data.push(dp);
                     inx++;
                }     
            }
            for (var j = 0; j < aData.length; j++) {
                if (aData[j][aData[j].length-1] < stIndex || aData[j][aData[j].length-1] > endIndex) {
                    continue;
                }
                var dpp = [];
                dpp.push(inx);
                for (var h=1;h<aData[j].length;h++) {
                    dpp.push(aData[j][h]);
                }
                data.push(dpp);
                inx++;
            }
            if (isFilled && endIndex > end) {   
                for (var g = end; g<endIndex; g+=interVal) {
                     var d = [inx,NaN,g+interVal];
                     data.push(d);
                     inx++;
                }     
            }
            return data;
        },
	    EMA: function(aData,n) {
	        if(typeof(aData)=="undefined"||aData.length==0||isNaN(n)){
				return null;
			}
	        var aCache = [];
	        var lg = aData.length, k  = 2/(n+1), iPreEma= 0, iSmv = 0,m=0;
	        var needCut = true, st = 0;;
	        for (var i = 0; i < lg; i++) {
	            if (needCut && (aData[i] == null || isNaN(aData[i]))) {
	                aCache.push(NaN);
	                st = i + 1;
	                continue;
	            }
	            needCut = false;
	            if ((i - st) < n - 1) {
	                aCache.push(NaN);
	                if (aData[i] != null && !isNaN(aData[i])) {
	                    iSmv += aData[i], m++;
	                }
	                continue;
	            } else if ((i - st) == n - 1) {
	                if (aData[i] != null && !isNaN(aData[i])) {
	                    iSmv += aData[i], m++;
	                }
	                aCache.push((iSmv == 0 ? NaN : (iSmv / m)));
	                if (!isNaN(aCache[i])) {
	                    iPreEma = aCache[i];
	                }
	            } else {
	                var iCurPrice = (aData[i] == null ? NaN : aData[i]);
	                var iEma = iPreEma + (iCurPrice - iPreEma) * k;
	                aCache.push(iEma);
	                if (!isNaN(aCache[i])) {
	                    iPreEma = iEma;
	                }
	            }
	        }
	        return aCache;
	    },
		calculateKeltner:function(aData,ty,e,t,a){
			if(!aData || !aData.length)return [];
			var arr=[],atr=[],ema=[],close=[],aa=[],bb=[],cc=[];
			for(var i =0;i<aData.length;i++){
				close.push(aData[i][1]);
			}
			atr = this.calculateAtr(aData,0,a);
			ema = this.EMA(close,e);
			for(var i =0;i<aData.length;i++){
				if(isNaN(ema[i])||isNaN(atr[i][1])){
					aa.push([i, NaN, aData[i][aData[i].length - 1]]);
					bb.push([i, NaN, aData[i][aData[i].length - 1]]);
					cc.push([i, NaN, aData[i][aData[i].length - 1]]);
				}else{
					aa.push([i, ema[i]+2*atr[i][1], aData[i][aData[i].length - 1]]);
					bb.push([i, ema[i], aData[i][aData[i].length - 1]]);
					cc.push([i, ema[i]-2*atr[i][1], aData[i][aData[i].length - 1]]);
				}
			}
			return [aa,bb,cc];
		},
		calculateAtr:function(aData,ty,p){
			if(!aData || !aData.length)return [];
			if(typeof(p)=="undefined"){
				p=14;
			}
			var arr = [],j=0,sum=0,hl=0,a=b=c=0,pre=0;
			for(var i = 0;i<aData.length;i++){
				
				a = aData[i][2]-aData[i][3];
				if(i>0){
					b = Math.abs(aData[i][2]-aData[i-1][1]);
					c = Math.abs(aData[i][3]-aData[i-1][1]);
				}
				if(i<p-1){
					if(i==0&&!isNaN(a)){
						j++;
						sum +=a;
					}else if(!isNaN(a)&&!isNaN(b)&&!isNaN(c)){
						j++;
						sum +=Math.max(Math.max(a,b),c);
					}
					arr.push([i, NaN, aData[i][aData[i].length - 1]]);
				}else if(i==p-1){
					if(!isNaN(a)&&!isNaN(b)&&!isNaN(c)){
						j++;
						sum +=Math.max(Math.max(a,b),c);
					}
					pre = sum/j;
					arr.push([i, pre, aData[i][aData[i].length - 1]]);
				}else{
					if(!isNaN(a)&&!isNaN(b)&&!isNaN(c)){
						pre = (pre*(p-1)+Math.max(Math.max(a,b),c))/p;
						arr.push([i, pre, aData[i][aData[i].length - 1]]);
					}else{
						arr.push([i, NaN, aData[i][aData[i].length - 1]]);
					}
				}
			}
			return arr;
		},
		calculateForceIndex:function(aData,volData,ty,p){
			if(!aData || !aData.length||volData.lenght==0)return [];
			var arr=[],ema=[];
			//arr.push([0, NaN, aData[0][aData[0].length - 1]]); 
			
			for(var i = 0;i<aData.length;i++){
				if(isNaN(aData[i][1])||isNaN(volData[i][1])||i==0){
					ema.push(NaN); 
				}else{
					ema.push((aData[i][1]-aData[i-1][1])*volData[i][1]); 
				}
			}
			ema = this.EMA(ema,p);
			for(var i =0;i<ema.length;i++){
				arr.push([i, ema[i], aData[i][aData[i].length - 1]]); 
			}
			return arr;
		},
		calculateVolatility:function(aData,ty,p,pa){
			if (!aData || aData.length==0) 
	            return [];
			var arr = [];
	        var arrHL = [],temp=0;
	        for (var i = 0; i < aData.length; i++) {
	            arrHL.push(aData[i][2] - aData[i][3]);
	        }
	        var arrEma1 = this.EMA(arrHL, p);
			for(var i = 0;i<aData.length;i++){
				if(i<(p+pa-1)){
					arr.push([i, NaN, aData[i][aData[i].length - 1]]); 
				}else{
					temp = (arrEma1[i]/arrEma1[i-pa]-1)*100;
					arr.push([i, temp, aData[i][aData[i].length - 1]]);
				}
			}
			return arr;
		},
		calculateMess:function(aData,ty){
	        if (!aData || !aData.length) 
	            return [];
	        var arr = [], previous = NaN, temp = 0;
	        var arrHL = [];
	        for (var i = 0; i < aData.length; i++) {
	            arrHL.push(aData[i][2] - aData[i][3]);
	        }
	        var arrEma1 = this.EMA(arrHL, 9);
	        var arrEma2 = this.EMA(arrEma1, 9);
	        var sum = 0,arrCompare=[];
	        for (var i = 0; i < arrEma2.length; i++) {
	            if (i < 16) {
	                arr.push([i, NaN, aData[i][aData[i].length - 1]]);
	                continue;
	            }
				arrCompare[i]=arrEma1[i]/arrEma2[i];
	            if (!isNaN(arrCompare[i])) {
	                sum += arrCompare[i];
	            }
	            if (i < 40) {
					arr.push([i, NaN, aData[i][aData[i].length - 1]]);
	                continue;
	            }
	            if (i > 40) {
	                if (!isNaN(arrCompare[i - 25])) {
	                    sum -= arrCompare[i - 25];
	                }
	            }
	            arr.push([i, sum, aData[i][aData[i].length - 1]]);
	        }
	        return arr;
		},
		calculateAccDis:function(aData,volData,ty){
			if(!aData || !aData.length||volData.lenght==0)return [];
			var arr =[],previous = NaN,temp=0;
			for(var i = 0;i<aData.length;i++){
				temp = (2*aData[i][1]-aData[i][2]-aData[i][3])*volData[i][1]/(aData[i][2]-aData[i][3])+(isNaN(previous)?0:previous);
				arr[i]=[i,temp,aData[i][aData[i].length - 1]];
				if(!isNaN(temp)){
					previous = temp;
				}
			}
			return arr;
		},
		calculateWMA:function(aData,ty,p){
			if(!aData || !aData.length)return [];
			if(typeof(p)=="undefined"||p<1){
				p=15;
			}
			var denominator  = p*(p+1)/2;
			var arr=[],tsum =0,ij=0;
			for(var i = 0;i<aData.length;i++){
				tsum =0;
				if(i<p-1){
					arr[i]=[i,NaN,aData[i][aData[i].length - 1]];
				}else {
					ij =1;
					for (var j = i - p + 1; j <= i; j++,ij++) {
						tsum += (isNaN(aData[j][1]) ? 0 : aData[j][1]) * ij;
					}
					arr[i] = [i, tsum / denominator, aData[i][aData[i].length - 1]];
				}
			}
			return arr;
		},
		calculateVolp:function(aData,volData,ty,n){
			if (aData==null||aData.length<n||volData==null) {
                return [];
            }
			var len = aData.length,vacc=[],arr=[],min = max= aData[0][1]
			for(var i = 1;i<len ;i++){
				max = Math.max(max,aData[i][1]);
				min = Math.min(min,aData[i][1]);
			}
			var avg = (max-min)/14;
			for(var i = 0;i<14;i++){
				if(i==0){
					arr.push([min,(min+avg),0])
				}else{
					arr.push([arr[i-1][1],(arr[i-1][1]+avg),0])
				}
			}
			var d=0;
			for(var i = 0;i<aData.length;i++){
				d = aData[i][1];
				if(d<arr[0][1]){
					arr[0][2] +=volData[i][1];
				}else if(d<arr[1][1]){
					arr[1][2] +=volData[i][1];
				}else if(d<arr[2][1]){
					arr[2][2] +=volData[i][1];
				}else if(d<arr[3][1]){
					arr[3][2] +=volData[i][1];
				}else if(d<arr[4][1]){
					arr[4][2] +=volData[i][1];
				}else if(d<arr[5][1]){
					arr[5][2] +=volData[i][1];
				}else if(d<arr[6][1]){
					arr[6][2] +=volData[i][1];
				}else if(d<arr[7][1]){
					arr[7][2] +=volData[i][1];
				}else if(d<arr[8][1]){
					arr[8][2] +=volData[i][1];
				}else if(d<arr[9][1]){
					arr[9][2] +=volData[i][1];
				}else if(d<arr[10][1]){
					arr[10][2] +=volData[i][1];
				}else if(d<arr[11][1]){
					arr[11][2] +=volData[i][1];
				}else if(d<arr[12][1]){
					arr[12][2] +=volData[i][1];
				}else if(d<arr[13][1]){
					arr[13][2] +=volData[i][1];
				}
			}
			return arr;
		},
		calculateDmi:function(aData,ty,n) {
			if (isNaN(n)||aData==null||aData.length<n) {
                return [];
            }
			var arr=[],dm=[],dm1=dm2=0,fk1=[],fk2=[],p=14,k=2/(p+1),t1=t2=0,tr=0,s1=s2=s3=0,e1=[],e2=[],e3=[],kp=0,di1=di2=0,dx=[],dxSum =0,adx=[],tmax=0;
			dm1[0]=dm2[0]=tr[0]=0,dm[0]=0,fk1[0]=0,fk2[0]=0;
			var a1=[],a2=[],a3=[];
			a1[0]=a2[0]=a3[0]=[0,NaN,aData[0][aData[0].length-1]];
			for(var i = 1;i<aData.length;i++){
				a1[i]=[0,NaN,aData[i][aData[i].length - 1]];
				a2[i]=[0,NaN,aData[i][aData[i].length - 1]];
				a3[i]=[0,NaN,aData[i][aData[i].length - 1]];
				t1 = aData[i][2]-aData[i-1][2];
				t2 = aData[i-1][3]-aData[i][3];
				dm1=dm2=0;
				if(t1>t2){
					dm1 = t1;
				}else if(t1<t2){
					dm2 = t2;
				}
				if(dm1<0){
					dm1=0;
				}
				if(dm2<0){
					dm2=0
				}
				if(dm1==dm2){
					dm1=0;
					dm2=0;
				}
				tmax = Math.max(dm1,dm2);
				if(tmax<dm[i-1]){
					dm1=0;
					dm2=0;
				}
				dm[i]=tmax;
				fk1[i];
				tr =Math.max(aData[i][2]-aData[i][3],Math.max(aData[i][2]-aData[i-1][1],aData[i][3]-aData[i-1][1]));
				if(i<p){
					s1 +=dm1;
					s2 +=dm2;
					s3 +=tr;
				}
				if(i ==(p-1)){
					e1[i]= s1/p;
					e2[i]=s2/p;
					e3[i]=s3/p;
					a1[i][1]=e1[i];
					a2[i][1]=e2[i];
				}
				kp = aData[i][1]*k;
				if(i>=p){
					e1[i]= kp+(1-k)*e1[i-1];
					e2[i]=kp+(1-k)*e2[i-1];
					e3[i]=kp+(1-k)*e3[i-1];
					di1=e1[i]/e3[i];
					di2=e2[i]/e3[i];
					dx[i] = Math.abs(di1-di2)*100/(di1+di2);
					a1[i][1]=e1[i];
					a2[i][1]=e2[i];
				}
				if(i>=p&&i<2*p){
					dxSum +=dx[i];
				}
				if(i==(2*p-1)){
					adx[i]=dxSum/p;
					a3[i][1]=adx[i];
				}
				if(i>=2*p){
					adx[i]=kp+(1-k)*adx[i-1];
					a3[i][1]=adx[i];
				}
			}
			return [a1,a2,a3];
		},
		calculatePc:function(aData,ty,n) {
			if (isNaN(n)||n<2||n>250||aData==null||aData.length<n) {
                return [];
            }
			var arr1=[],arr2=[],max=aData[0][2],min=aData[0][3],imax=imin=0;
			arr1.push([0,NaN,aData[0][aData[0].length - 1]]);
			arr2.push([0,NaN,aData[0][aData[0].length - 1]]);
			for(var i = 1;i<aData.length;i++){
				if(max<=aData[i][2]){
					max = aData[i][2];
					imax  =i;
				}
				if(min>=aData[i][3]){
					min = aData[i][3];
					imin = i;
				}
				if((i-n)==imax){
					max =0;
					var begin = imax +1,end = imax +n+1;
					for(var k = begin;k<end;k++){
						if(max <=aData[k][2]){
							max = aData[k][2];
							imax  =k;
						}
					}
				}
				if((i-n)==imin){
					var begin = imin +2,end = imin +n+1;
					min = aData[begin-1][3];
					imin = begin-1;
					for(var k = begin;k<end;k++){
						if(min>=aData[k][3]){
							min = aData[k][3];
							imin = k;
						}
					}
				}
				if(i>n-2){
					arr1.push([i,max,aData[i][aData[i].length - 1]]);
					arr2.push([i,min,aData[i][aData[i].length - 1]]);
					
				}else{
					arr1.push([i,NaN,aData[i][aData[i].length - 1]]);
					arr2.push([i,NaN,aData[i][aData[i].length - 1]]);
				}
			}
			return [arr1,arr2];
		},
		calculateMaen:function(aData,ty,n,per) {
			if (isNaN(n)||isNaN(per)||n<0||n>250||aData==null||aData.length<n) {
                return [];
            }
			var arr1=[],arr2=[],vol=[],sum=0,d=0,d1=0,d2=0;
			for(var i = 0;i<aData.length;i++){
				sum +=aData[i][1];
				if(i<n){
					if(i==(n-1)){
						vol =[i,sum/n,aData[i][aData[i].length - 1]];
						d=sum/n;
						d1 =d*(100+per)/100;
						d2 =d*(100-per)/100;
					}else{
						vol =[i,NaN,aData[i][aData[i].length - 1]];
						d1=d2=NaN;
					}
				}else{
					sum -=aData[i-n][1];
					d = sum/n;
					d1 =d*(100+per)/100;
					d2 =d*(100-per)/100;
				}
				arr1.push([i,d1,aData[i][aData[i].length - 1]]);
				arr2.push([i,d2,aData[i][aData[i].length - 1]]);
			}
			return [arr1,arr2];
		}
		,
		calculateVol:function(aData,volData,ty,n) {
			if (isNaN(n)||volData==null||volData.length<n) {
                return [];
            }
			var arr=[],vol=[],sum=0;
			for(var i = 0;i<volData.length;i++){
				sum +=volData[i][1];
				if(i<n){
					if(i==(n-1)){
						vol =[i,sum/n,aData[i][aData[i].length - 1]];
					}else{
						vol =[i,NaN,aData[i][aData[i].length - 1]];
					}
				}else{
					sum -=volData[i-n][1];
					vol =[i,sum/n,aData[i][aData[i].length - 1]];
				}
				arr.push(vol);
			}
			return arr;
		},
		calculateUlt:function(aData,ty,n) {
            if (isNaN(n)|| aData == null || aData.length < n) {
                return [];
            }
            var arr=[],bp=[],tr=[],d=0,ult=[],k=0,bpSum=0,trSum=0,temp=0,result=0;
			for(var i = 0;i<aData.length;i++){
				d = aData[i];
				if(i==0){
					bp[i]=d[1]-d[3];
					tr[i]=d[2]-d[3];
				}else{
					bp[i]=d[1]-Math.min(d[3],aData[i-1][1]);
					tr[i]=Math.max(d[2],aData[i-1][1])-Math.min(d[3],aData[i-1][1]);
				}
				if(i<28){
					bpSum +=bp[i];
					trSum +=tr[i];
					if(i==(k+6)){
						ult[k]=[];
						ult[k][0]=[bpSum,trSum];
					}
					if(i==(k+13)){
						ult[k][1]=[bpSum,trSum];
					}
					if(i==(k+27)){
						ult[k][2]=[bpSum,trSum];
					}
				}
				if(i>=27){
					if(k>0){
						temp = ult[k-1];
						ult[k]=[];
						ult[k][0]=[temp[0][0]-bp[i-28]+bp[i-21],temp[0][1]-tr[i-28]+tr[i-21]];
						ult[k][1]=[temp[1][0]-bp[i-28]+bp[i-14],temp[1][1]-tr[i-28]+tr[i-14]];	
						ult[k][2]=[temp[2][0]-bp[i-28]+bp[i],temp[2][1]-tr[i-28]+tr[i]];
					}
					result = 100*(4*ult[k][0][0]/ult[k][0][1]+2*ult[k][1][0]/ult[k][1][1]+ult[k][2][0]/ult[k][2][1])/7;
					arr.push([i,result,aData[i][aData[i].length - 1]]);
					k++;
				}else{
					arr.push([i,NaN,aData[i][aData[i].length - 1]]);
				}
			}
			return arr;
        },
        calculateMom:function(aData,ty,n) {
            if (isNaN(n)||n<1||n>199 || aData == null || aData.length < n) {
                return [];
            }
            var arr=[];
			for(var i = 0;i<aData.length;i++){
				arr.push((i<n?[i,NaN,aData[i][aData[i].length - 1]]:[i,(aData[i][1]-aData[i-n][1]),aData[i][aData[i].length - 1]]));
			}
			return arr;
        },
		calculateMfi:function(aData,volData,ty,n){
			if(isNaN(n)||n<1||n>99){return [];}
			var len = aData.length;
			var typicalp=[],pn=[],pmf=0,nmf=0,arr=[],temp;
			for(var i = 0;i<len;i++){
				temp =[i,NaN,aData[i][aData[i].length - 1]];
				if (aData[i][1] == 0) { //no close price
					pn[i] = 0;
				} else {
					typicalp[i] = (aData[i][1] + aData[i][2] + aData[i][3]) / 3;
					if (i > 0) {
						pn[i - 1] = typicalp[i] > typicalp[i - 1] ? 1 : (typicalp[i] == typicalp[i - 1] ? 0 : -1);
						if (pn[i - 1] > 0) {
							pmf += typicalp[i] * volData[i][1];
						} else if (pn[i - 1] < 0) {
							nmf += typicalp[i] * volData[i][1];
						}
						if (i >= n) {
							if (i>n) {
								if (pn[i - n - 1] > 0) {
									pmf -= typicalp[i - n] * volData[i - n][1]
								} else if (pn[i - n - 1] < 0) {
									nmf -= typicalp[i - n] * volData[i - n][1];
								}
							}
							temp[1] = 100*pmf/(pmf+nmf);
						}
					}
				}
				arr.push(temp);
			}
			return arr;
		},
		calculateVacc:function(aData,volData,ty,n){
			 // ty>10 volume data ty=1 historical daily data; ty=2 historical weekily data; ty=3 historical monthly data; ty=0 intraydayData.
			var len = aData.length;
			var vacc=[],arr=[];
			for(var i = 0;i<len;i++){
				if (aData[i][1] == undefined || aData[i][1] == null || isNaN(aData[i][1]) || aData[i][1] == 0) { //no close price
					vacc[i] = NaN;
				} else {
					vacc[i] = volData[i][1] * (aData[i][1] - (aData[i][2] + aData[i][3]) / 2);
				}
				arr.push([i,vacc[i],aData[i][aData[i].length-1]]);			
			}
			return arr;
		},	
		calculateObv:function(aData,volData,ty,n){
			var sCacheKey = ty+"_"+n,  aCachedData = this.cachedData.obvData;
			if (ty > 0 && ty != 10 && aCachedData[sCacheKey] != null) {                // ty>10 volume data ty=1 historical daily data; ty=2 historical weekily data; ty=3 historical monthly data; ty=0 intraydayData.
                return aCachedData[sCacheKey];
            }
			var len = aData.length;
			var obv=[],arr=[];
			for(var i = 0;i<len;i++){
				if(i==0){
					obv[i]=volData[0][1];
				}else{
					if (aData[i][1] == undefined || aData[i][1] == null || isNaN(aData[i][1]) || aData[i][1] == 0) { //no close price
						obv[i] = NaN;
					}else{
						if(aData[i][1]>aData[i-1][1]){
							obv[i] = obv[i-1]+volData[i][1];
						}else if(aData[i][1]==aData[i-1][1]){
							obv[i] =obv[i-1];
						}else if(aData[i][1]<aData[i-1][1]){
							obv[i] =obv[i-1]-volData[i][1];
						}
					} 
				}
				arr.push([i,obv[i],aData[i][aData[i].length-1]]);			
			}
			return arr;
		},
		calculateUd:function(aData,volData,ty,m,n){
			if(isNaN(n)||n<1||n>99||isNaN(m)||m<1||m>99){
				return [];
			}
			var len =aData.length;
			var arr=[],close=[],sup=sdown=0,ud=[];
			for (var i = 1, j = 0; i < len; i++, j++) {
				if (aData[i][1] == undefined || aData[i][1] == null || isNaN(aData[i][1]) || aData[i][1] == 0) {
					close[i - 1] = 0;
				} else if (aData[i][1] > aData[i - 1][1]) {
					close[i - 1] = 1;
				} else if (aData[i][1] < aData[i - 1][1]) {
					close[i - 1] = -1;
				} else {
					close[i - 1] = 0;
				}
				if (close[j] == 1) {
					sup += volData[j + 1][1];
				} else if (close[j] == -1) {
					sdown += volData[j + 1][1];
				}
				if (j < m - 1) {
					ud[j] = -1;
					continue;
				}
				if (j >= m) {
					if (close[j - m] == 1) {
						sup -= volData[j - m + 1][1];
					} else if (close[j - m] == -1) {
						sdown -= volData[j - m + 1][1];
					}
				}
				ud[j] = [sup, sdown];
			}
			var mnlen = m+n,sum = 0,harr=[];
			arr.push([0,NaN,aData[0][aData[0].length-1]]);
			for(var i = 0;i<ud.length;i++){
				if(ud[i]==-1){
					arr.push([i,NaN,aData[i][aData[i].length-1]]);
					continue;
				}
				harr[i]=ud[i][1]==0?Number.POSITIVE_INFINITY:(ud[i][0]/ud[i][1]);
				sum +=harr[i];
				if(i<mnlen-2){
					arr.push([i,NaN,aData[i][aData[i].length-1]]);
				}else{
					if(i>mnlen-2){
						sum -=harr[i-n];
					}
					arr.push([i+1,sum/5,aData[i+1][aData[i+1].length-1]]);
				}
			}
			return arr;
		},
        calculateSma:function(aData,ty,n) {
            if (n == null || n< 0 || aData == null || aData.length < n) {
                return null;
            }
            var sCacheKey = ty+"_"+n,  aCachedData = this.cachedData.smaData;
            if (ty > 0 && ty != 10 && aCachedData[sCacheKey] != null) {                // ty>10 volume data ty=1 historical daily data; ty=2 historical weekily data; ty=3 historical monthly data; ty=0 intraydayData.
                return aCachedData[sCacheKey];
            }
            aCachedData[sCacheKey] = []; 
            var aCache = aCachedData[sCacheKey];
            var lg = aData.length, iSum = 0, m=0;
			var st = 0;
            for (var i = 0; i<lg; i++) {
				if(aData[i] == null || isNaN(aData[i][1])){        // cut the invalid value.
					aCache.push([i,NaN,aData[i][aData[i].length-1]]);
					st = i+1;
					continue;
				} else {
                   iSum += aData[i][1];
                   m++;
                }
                if ((i-st) < n-1) {
                    aCache.push([i,NaN,aData[i][aData[i].length-1]]);
                } else { 
                    var smv = m>0?(iSum/m):NaN; 
                    aCache.push([i,smv,aData[i][aData[i].length-1]]);
                    if (aData[i-n+1] != null && !isNaN(aData[i-n+1][1])) {
                        iSum-=aData[i-n+1][1];
                        m--;
                    }
                }           
            }
            return aCache;
        },
        
        calculateEma: function(aData,ty,n) {
            if (n == null || n< 0 || aData == null || aData.length < n) {
               return null;
            }
            var sCacheKey = ty+"_"+n; var aCachedData = this.cachedData.emaData;
            if (ty > 0 && aCachedData[sCacheKey] != null) {                                      // ty=1 historical daily data; ty=2 historical weekily data; ty=3 historical monthly data; ty=0 intraydayData.
               return aCachedData[sCacheKey]; 
            } 
            aCachedData[sCacheKey] = []; 
            var aCache = aCachedData[sCacheKey];
            var lg = aData.length, k  = 2/(n+1), iPreEma= 0, iSmv = 0,m=0;
            var needCut = true, st = 0;
            for (var i=0;i<lg;i++) {
                if(needCut && (aData[i] == null || isNaN(aData[i][1]))) {   
                    aCache.push([i,NaN,aData[i][aData[i].length-1]]);
                    st = i+1;
                    continue;
                }
                needCut = false; 
                if ((i-st) < n-1) { 
                     aCache.push([i,NaN,aData[i][aData[i].length-1]]);
                     if (aData[i] != null && !isNaN(aData[i][1])) {
                         iSmv+=aData[i][1], m++;
                     }
                     continue;
                } else if ((i-st) == n-1) { 
                     if (aData[i] != null && !isNaN(aData[i][1])) {
                         iSmv+=aData[i][1], m++;
                     }
                     aCache.push([i,(iSmv == 0?NaN:(iSmv/m)),aData[i][aData[i].length-1]]);
                     if (!isNaN(aCache[i][1]) ) {
                         iPreEma = aCache[i][1];
                     }
                } else { 
                     var iCurPrice = (aData[i] ==null? NaN:aData[i][1]); 
                     var iEma = iPreEma + (iCurPrice-iPreEma)*k;
                     aCache.push([i,iEma,aData[i][aData[i].length-1]]); 
                     if (!isNaN(aCache[i][1])) { 
                         iPreEma = iEma;
                     }
                }
            }
            return aCache;
        },
        
        calculateBBands:function(aData,ty,n,dev) { 
            if (n< 0 || aData == null || aData.length < n) {
               return;
            } 
            var sCacheKey = ty+"_"+n+"_"+dev; 
            var aCachedData = this.cachedData.bBandsData;
            if (ty>0 && aCachedData[sCacheKey] != null) {               // ty=1 historical daily data; ty=2 historical weekily data; ty=3 historical monthly data; ty=0 intraydayData.
                return aCachedData[sCacheKey];
            }  
            aCachedData[sCacheKey] = []; 
            var aCache = aCachedData[sCacheKey];
            var lg = aData.length; aCache[0] = [], aCache[1] = [];
            var iSum = 0, m = 0;
            for (var i = 0; i < lg; i++) { 
                if (i < n-1) {
                    aCache[0].push([i,NaN,aData[i][aData[i].length-1]]);aCache[1].push([i,NaN,aData[i][aData[i].length-1]]);
                    if (aData[i] != null && !isNaN(aData[i][1])) {
                        iSum += aData[i][1],
                        m++;
                    }
                    continue;
                } else { 
                    if (aData[i] != null && !isNaN(aData[i][1])) {
                        iSum+= aData[i][1];
                        m++;
                    } 
                    var iAvg = m>0?(iSum/m):NaN; var iStdDev = 0,iStdDevSum = 0,  iNum =0;
                    for (var j = i; j > (i-n); j--) {
                        if (aData[j] != null && !isNaN(aData[j][1])) {
                            iNum++;
                            iStdDevSum += (Math.pow((aData[j][1]-iAvg),2));
                        }
                    }
                    if(iNum > 1) iNum = iNum -1; // 
                    iStdDev = Math.sqrt(iStdDevSum/iNum);
                    var ibBandUpper = iAvg + dev*iStdDev;
                    var ibBandLower = iAvg - dev*iStdDev; 
                    aCache[0].push([i,ibBandUpper,aData[i][aData[i].length-1]]);
                    aCache[1].push([i,ibBandLower,aData[i][aData[i].length-1]]);
                    if (aData[i-n+1] != null && !isNaN(aData[i-n+1][1])) {
                       iSum -= aData[i-n+1][1] ;
                       m--;
                    }
                }                
            }
            return aCache;
        },
        
        calculateMACD:function(aData,ty,slow,fast,signal) {
            if (fast < 0 || aData == null || aData.length < fast) {
                return;
            }
            var sCacheKey = ty+"_"+slow+"_"+fast+"_"+signal; var aCachedData = this.cachedData.macdData;
            if (ty>0 && aCachedData[sCacheKey] != null) {      // ty=1 historic
                return aCachedData[sCacheKey]; 
            }
            aCachedData[sCacheKey] = []; 
            var aCache = aCachedData[sCacheKey];
            aCache[0] = [], aCache[1] = [], aCache[2] = [];
            var slowEma = this.calculateEma(aData,ty,slow);
            var fastEma = this.calculateEma(aData,ty,fast);
            var lg = aData.length;
            var iMacd, divergence;
            for (var i = 0; i < lg; i++) {
                if(isNaN(slowEma[i][1])) {
                    iMacd = NaN;
                } else {
                    iMacd = fastEma[i][1] - slowEma[i][1];
                }
                aCache[0][i] = [i,iMacd,aData[i][aData[i].length-1]];
            }
            var sigualEma = this.calculateEma(aCache[0],ty,signal);
            for (j = 0;j<lg;j++) { 
                divergence = aCache[0][j][1] - sigualEma[j][1];  
                aCache[2][j] = [j,divergence,aData[j][aData[j].length-1]];
            }
            aCache[1] = sigualEma;
            return aCache;
        },
        
        calculateRSI : function (aData,ty,n){
            if (n< 0 || aData == null || aData.length < n) {
               return;
            }
            var sCacheKey = ty+"_"+n;
            var aCachedData = this.cachedData.rsiData;
            if (ty > 0 && aCachedData[sCacheKey] != null) {                             // ty=1 historical daily data; ty=2 historical weekily data; ty=3 historical monthly data; ty=0 intraydayData.
                return aCachedData[sCacheKey];
            } 
            aCachedData[sCacheKey] = []; 
            var aCache = aCachedData[sCacheKey], lg = aData.length;
            var iGain = 0, iLoss = 0,m = 0, iTemp = NaN, iTempLoss = NaN;
            for (var i = 0; i < lg; i++) {
                if (i < n) {
                    aCache[i] = [i,NaN,aData[i][aData[i].length-1]];
                    if (i>0 && !isNaN(aData[i][1])) {
                        var dx = aData[i][1] - aData[i-1][1]; 
                        if (dx > 0) { 
                            iGain+=dx;
                        } else {
                            iLoss+=dx;
                        }
                        m++;
                    }
                } else if (i == n) { 
                    var dx = aData[i][1] - aData[i-1][1]; 
                    if (dx > 0) { 
                       iGain += dx;
                    } else {
                       iLoss+=dx;
                    }
                    m++;
                    var iAvgGain = m>0?iGain/m:NaN, iAvgLoss = m>0?iLoss/m:NaN;
                    var iRsi = 100-(100/(1+Math.abs(iAvgGain/iAvgLoss)));
                    aCache[i] = [i,iRsi,aData[i][aData[i].length-1]];
                    iTemp = iAvgGain; 
                    iTempLoss = iAvgLoss;
                } else {
                    var dx = aData[i][1] - aData[i-1][1]; 
                    var dxLoss = dx<0 ?dx:0, dxGain = dx>0?dx:0;
                    var iAvgGain = (iTemp*(n-1)+dxGain)/n, iAvgLoss = (iTempLoss*(n-1)+dxLoss)/n;
                    var iRsi = 100-(100/(1+Math.abs(iAvgGain/iAvgLoss)));
                    aCache[i] = [i,iRsi,aData[i][aData[i].length-1]];
                    iTemp = iAvgGain; 
                    iTempLoss = iAvgLoss;
                }
              
            }
            return aCache;
        },
        
        _calculateStochastic: function(aData,ty,k,d,y) {
            if (k < 0 || aData == null || aData.length < k) { 
                return;
            }
            var sCacheKey = ty+"_"+k+"_"+d;
            var aCachedData = (y=="slow"?this.cachedData.slowStochasticData:this.cachedData.fastStochasticData);
            if (ty > 0 && aCachedData[sCacheKey] != null) {       // ty=1 historic
                return aCachedData[sCacheKey];  
            }
            aCachedData[sCacheKey] = []; 
            var aCache = aCachedData[sCacheKey]; 
            aCache[0] = []; aCache[1] = [];
            /*if (ty == 0) {
                return [];  // intraday data.
            }*/
            var lg = aData.length;
            for (var i = 0; i< lg; i++) {
                if (i < (k - 1)) {
                    aCache[0][i] = [i,NaN,aData[i][aData[i].length-1]];
                } else { 
                    var iMax = 0; iMin = 1000000;
                    for (j = i; j > i-k; j--) {
                        if (aData[j][2] > iMax) {
                            iMax = aData[j][2];
                        }
                        if (aData[j][3] < iMin) {
                            iMin = aData[j][3];
                        }
                    }
                    var iK = (iMax<=iMin?NaN:100*(aData[i][1] - iMin)/(iMax-iMin));
                    aCache[0][i] = [i,iK,aData[i][aData[i].length-1]];
                }    
            }
			var aSoure = aCache[0], lgg = aSoure.length, iSum = 0, m = 0;
                for (var h = 0;h < lgg; h++) {
                     if (h < (k+d-2)) {
                         aCache[1][h] = [h,NaN,aSoure[h][2]]; 
                         if (!isNaN(aSoure[h][1])) {
                             iSum += aSoure[h][1];
                             m++;
                         } 
                     } else {
                         if (!isNaN(aSoure[h][1])) {
                             iSum+=aSoure[h][1];
                             m++;
                         } 
                         aCache[1][h] = [h,(m>0?iSum/m:NaN),aSoure[h][2]];
                         if (!isNaN(aSoure[h-d+1][1])) {
                            iSum-=aSoure[h-d+1][1];
                            m--;
                         }
                     }
                }  
            return aCache;
        },
        
        calculateSlowStochastic:function(aData,ty,k,d) {
            return this._calculateStochastic(aData,ty,k,d,"slow");
        },
        
        calculateFastStochastic:function(aData,ty,k,d) {
            return this._calculateStochastic(aData,ty,k,d,"fast");
        },
        
        calculateROC:function (aData,ty,n) {
            if (n< 0 || aData == null || aData.length < n) {
                return null;
            }
            var sCacheKey = ty+"_"+n;
            var aCachedData = this.cachedData.rocData;
            if (ty > 0 && aCachedData[sCacheKey] != null) {      // ty=1 historic
               return aCachedData[sCacheKey];
            }  
            aCachedData[sCacheKey] = [];
            aCache = aCachedData[sCacheKey];
            var lg = aData.length;
			var preClose,roc;
            for (var i = 0;i < lg; i++) { 
                if (i < n) {
                    aCache.push([i,NaN,aData[i][aData[i].length-1]]);
                } else {
                    preClose = (aData[i-n] == null?NaN:aData[i-n][1]); 
                   	roc = NaN;
                    if (!isNaN(preClose)) {
                        roc = 100*(aData[i][1] - preClose)/preClose;
                    }
                    aCache[i] = [i,roc,aData[i][aData[i].length-1]];
                }
            }
            return aCache;
        },
        
        calculateWillR:function(aData,ty,n) { 
            if (n < 0 || aData == null || aData.length < n) {
                return;
            }
            var sCacheKey = ty+"_"+n; 
            var aCachedData = this.cachedData.willRData;
            if (ty > 0 && aCachedData[sCacheKey] != null) {    // ty=1 historic
                return aCachedData[sCacheKey];
            } 
            aCachedData[sCacheKey] = []; 
            aCache = aCachedData[sCacheKey]; 
            var lg = aData.length;
            var iHigh = 0, iLow = 1000000,iR;
            for (var i = 0; i < lg; i++) { 
                if (i < n) {
                    if (aData[i] != null) {
						if (!isNaN(aData[i][2]) && aData[i][2] > iHigh) { 
                            iHigh = aData[i][2];
                        }
                        if (!isNaN(aData[i][3]) && aData[i][3] < iLow) {
                            iLow = aData[i][3];
                        }
                        if (i == n-1) { 
                            iR = 100*(aData[i][1]-iHigh)/(iHigh-iLow); 
                            aCache[i] = [i,iR,aData[i][aData[i].length-1]]; 
                        } else {
                            aCache[i] = [i,NaN,aData[i][aData[i].length-1]];
                        }
                    }
                } else {
                    iHigh = 0, iLow = 1000000;
                    for (var j = i; j >i - n; j--) {
                        if (!isNaN(aData[j][2]) && aData[j][2] > iHigh) {
                            iHigh = aData[j][2];
                        }
                        if (!isNaN(aData[j][3]) && aData[j][3] < iLow) {
                            iLow = aData[j][3];
                        }
                    }
                    iR = 100*(aData[i][1]-iHigh)/(iHigh-iLow);
					aCache[i] = [i,iR,aData[i][aData[i].length-1]];
                }         
            }
            return aCache;
        },
        
        calculatePSAR:function(aData,ty,a,maxA) {
            if (aData == null || aData.length < 2) {
                return;
            }
            var sCacheKey = ty+"_"+a+"_"+maxA; 
            var aCachedData = this.cachedData.pSAR;
            if (ty > 0 && aCachedData[sCacheKey] != null) {             // ty=1 historic
                return aCachedData[sCacheKey];
            }  
            aCachedData[sCacheKey] = [];
            aCache = aCachedData[sCacheKey];
            var lg = aData.length;
            var iTrend, iEp, iA = a, iSAR, iMax = 0, iMin = 1000000; 
            var preTrend = [,];
            aCache[0] = [0,NaN,aData[0][aData[0].length-1]];
            for (var i = 2; i <= lg; i++) { 
                if (i == 2) {
                    var mm = aData[0][2]>aData[1][2]?aData[0][2]:aData[1][2]; 
                    var nn = aData[0][3]<aData[1][3]?aData[0][3]:aData[1][3];
                    if (aData[2][1] >= aData[1][1]) {     // up trend
                        iTrend = 0; iSAR  = nn; 
                        iEp = mm; aCache[1] = [1,iSAR,aData[2][aData[2].length-1]]; 
                        preTrend[0] = preTrend[1] = 0;
                    } else {                                       // down trend.
                        iTrend  = 1; iSAR =mm; 
                        iEp = nn; aCache[1] = [1,iSAR,aData[1][aData[1].length]];
                        preTrend[0] = preTrend[1] = 0;
                    } 
                }
                var iCurrentSAR = iSAR + iA*(iEp-iSAR); 
                if (i == lg) {
                    aCache[i-1] = [i-1,iCurrentSAR,aData[i-1][aData[i-1].length-1]];
                    break;
                }
                if (isNaN(aData[i][1]) || isNaN(aData[i][2]) || isNaN(aData[i][3])) {
                    aCache[i] = [i,NaN,aData[i][aData[i].length-1]];
                    continue;
                }
                if (preTrend[0] == preTrend[1]) {
                    var min,max
                    if (preTrend[1] == 0) {                                                                  //up trend
                        if (i>1 && !isNaN(aData[i-1][3]) && !isNaN(aData[i-2][3])) {         
                            min = (aData[i-1][3]<aData[i-2][3]?aData[i-1][3]:aData[i-2][3]); 
                            if (iCurrentSAR > min) { 
                                iCurrentSAR = min;
                            }
                        }
                    } else {                                                                                      //down trend
                        if (i>1&& !isNaN(aData[i-1][2]) && !isNaN(aData[i-2][2])) {
                            max = (aData[i-1][2]>aData[i-2][2]?aData[i-1][2]:aData[i-2][2]);
                            if (iCurrentSAR < max) {
                                iCurrentSAR = max;
                            }
                        }
                    }             
                } else {
                    iCurrentSAR = iEp;
                }
                aCache[i-1] = [i-1,iCurrentSAR,aData[i-1][aData[i-1].length-1]];
                if (preTrend[1] == 1) {
                    if(aData[i][3] < iEp) { 
                        iEp = aData[i][3]; 
                        if (iA+0.02 <= maxA) iA = iA+0.02;
                     }
                } else {  
                    if (aData[i][2] > iEp) {
                        iEp = aData[i][2];
                        if (iA+0.02 <= maxA) iA = iA+0.02;
                    }
                }                  
                if ((preTrend[1]==0 && iCurrentSAR > aData[i][3]) || (preTrend[1] == 1 && iCurrentSAR < aData[i][2])) {
                    iA = a;
                    if (iTrend == 0) { 
                        iTrend = 1;
                    } else {
                        iTrend  = 0;
                    }
                } 
                iSAR = iCurrentSAR;
                preTrend [0] = preTrend[1];
                preTrend [1] = iTrend;
            }
            return aCache;
        }
        
    };
     
</script>
    </head>

    <body>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="keltnerInputData" type="text" style=
            "height:40px; width:760px; " value="[[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19]]"/>
        </div>
		<br/>Period EMA:<input id="kemaP" type="text" style=
            "height:40px; width:760px; " value="20"/>
		<br/>Times:<input id="ktimesP" type="text" style=
            "height:40px; width:760px; " value="2"/>
		<br/>Period Atr:<input id="katrP" type="text" style=
            "height:40px; width:760px; " value="10"/>
		<br/>
            <input type=
            "button" value="Keltner" onclick="calKeltner()" />
        </div>

        <div id="keltnerOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="atrInputData" type="text" style=
            "height:40px; width:760px; " value="[[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19]]"/>
        </div>
		<br/>
            <input type=
            "button" value="Atr" onclick="calAtr()" />
        </div>

        <div id="atrOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input,, //close<br/>data:<input id="forceIndexInputData" type="text" style=
            "height:40px; width:760px; " value="12,11,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78,11,32,56,85,25,45,86"/>
        </div>
		<br/>
		volume:<input id="forceIndexVolume" type="text" style=
            "height:40px; width:760px; " value="12,52,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78,11,32,56,85,25,45,86"/>
      	<br/>Period:<input id="forceIndexP" type="text" style=
            "height:40px; width:760px; " value="13"/>
        <div>
            <input type="button" value="forceIndex" onclick="calforceIndex()" />
        </div>

        <div id="forceIndexOutData">
        </div>
<p>-------------------</p>
    	<div>
            input,, //close<br/>data:<input id="volatilityInputData" type="text" style=
            "height:40px; width:760px; " value="[[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19]]"/>
        </div>
		<br/>
		Period:<input id="volatilityP" type="text" style=
            "height:40px; width:760px; " value="10"/>%
      	<br/> Period Ago:<input id="volatilityAgo" type="text" value="10"/>
        <div>
            <input type="button" value="Volatility" onclick="calVolatility()" />
        </div>

        <div id="volatilityOutData">
        </div>
<p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="messInputData" type="text" style=
            "height:40px; width:760px; " value="[[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19]]"/>
        </div>
		<br/>
            <input type=
            "button" value="Mess" onclick="calMess()" />
        </div>

        <div id="messOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="accdisInputData" type="text" style=
            "height:40px; width:760px; " value="[[25,30,15],[40,50,25],[28,30,19],[32,50,12],[64,80,40],[42,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[27,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20]]"/>
        </div>
		<br/>
		volume:<input id="accdisVolume" type="text" style=
            "height:40px; width:760px; " value="21,52,52,21,62,80,70,61,12,21,52,52,21,62,82,70,61,13,21,52,52,21,62,80,70,61,12"/>
      
        <div>
            <input type=
            "button" value="AccDis" onclick="calAccDis()" />
        </div>

        <div id="accdisOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input,,,, //close<br/>data:<input id="wmapInputData" type="text" style=
            "height:40px; width:760px; " value="21,52,52,21,62,80,70,61,12,21,52,52,21,62,82,70,61,13,21,52,52,21,62,80,70,61,12"/>
        </div>
		<br/> Period:<input id="wmaP" type="text" value="10"/>
        <div>
            <input type=
            "button" value="WMA" onclick="calWMA()" />
        </div>

        <div id="wmapOutData">
        </div>

        <p>-------------------</p>
		
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="volpInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20]]"/>
        </div>
		<br/>
		volume:<input id="volpVolume" type="text" style=
            "height:40px; width:760px; " value="21,52,52,21,62,80,70,61,12,21,52,52,21,62,82,70,61,13,21,52,52,21,62,80,70,61,12"/>
      
        <div>
            <input type=
            "button" value="VolP" onclick="calVOLP()" />
        </div>

        <div id="volpOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="dmiInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[32,50,12],[64,80,40],[32,50,32],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40]]"/>
        </div>
		<br/>
        <div>
            <input type=
            "button" value="DMI" onclick="calDMI()" />
        </div>

        <div id="dmiOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="pcInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[32,50,12],[64,80,40],[32,50,32],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40]]"/>
        </div>
			<br/> Period:<input id="pcP" type="text" value="2"/>
        <div>
            <input type=
            "button" value="PC" onclick="calPC()" />
        </div>

        <div id="pcOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input,, //close<br/>data:<input id="maenInputData" type="text" style=
            "height:40px; width:760px; " value="12,11,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78"/>
        </div>
		<br/>
		percent:<input id="maenPer" type="text" style=
            "height:40px; width:760px; " value="2"/>%
      	<br/> Period:<input id="maenP" type="text" value="2"/>
        <div>
            <input type="button" value="MA Envelope" onclick="calMAEN()" />
        </div>

        <div id="maenOutData">
        </div>
<p>-------------------</p>
    	<div>
            input,, //close<br/>data:<input id="volInputData" type="text" style=
            "height:40px; width:760px; " value="12,11,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78"/>
        </div>
		<br/>
		volume:<input id="volVolume" type="text" style=
            "height:40px; width:760px; " value="12,52,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78"/>
      	<br/> Period:<input id="volP" type="text" value="2"/>
        <div>
            <input type="button" value="Vol+" onclick="calVOL()" />
        </div>

        <div id="volOutData">
        </div>
<p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="ultInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[32,50,12],[64,80,40],[32,50,32],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40]]"/>
        </div>
		<br/>
        <div>
            <input type=
            "button" value="ULT" onclick="calULT()" />
        </div>

        <div id="ultOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input(,) //close<br/>data:<input id="momInputData" type="text" style=
            "height:40px; width:760px; " value="12,11,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78"/>
        </div>
		<br/>
        <div>
            Period:<input id="momP" type="text" value="2"/> <input type=
            "button" value="MOM" onclick="calMOM()" />
        </div>

        <div id="momOutData">
        </div>

        <p>-------------------</p>
    	<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="mfiInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20]]"/>
        </div>
		<br/>
		volume:<input id="mfiVolume" type="text" style=
            "height:40px; width:760px; " value="21,52,52,21,62,80,70,61,12,21,52,52,21,62,82,70,61,13,21,52,52,21,62,80,70,61,12"/>
      
        <div>
            Period:<input id="mfiP" type="text" /> <input type=
            "button" value="MFI" onclick="calMFI()" />
        </div>

        <div id="mfiOutData">
        </div>

        <p>-------------------</p>
		<div>
            input[[,,,],[,,,]] //close,high,low<br/>data:<input id="vaccInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20]]"/>
        </div>
		<br/>
		volume:<input id="vaccVolume" type="text" style=
            "height:40px; width:760px; " value="21,52,52,21,62,80,70,61,12,21,52,52,21,62,82,70,61,13,21,52,52,21,62,80,70,61,12"/>
      
        <div>
            <input type=
            "button" value="VACC" onclick="calVACC()" />
        </div>

        <div id="vaccOutData">
        </div>

        <p>-------------------</p>
				<div>
            input,,, //close<br/>data:<input id="obvInputData" type="text" style=
            "height:40px; width:760px; " value="12,11,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78"/>
        </div>
		<br/>
		volume:<input id="obvVolume" type="text" style=
            "height:40px; width:760px; " value="12,52,32,56,85,25,45,86,24,56,36,62,76,51,56,85,56,56,52,78"/>
      
        <div>
            <input type="button" value="OBV" onclick="calOBV()" />
        </div>

        <div id="obvOutData">
        </div>
<p>-------------------</p>
				<div>
            input,,, //close<br/>data:<input id="udInputData" type="text" style=
            "height:40px; width:760px; " value="[[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[31,51,27],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20],[20,30,15],[30,50,25],[22,30,19],[32,50,12],[64,80,40],[32,50,32],[42,45,30],[55,55,40],[40,41,20]]"/>
        </div>
		<br/>
		volume:<input id="udVolume" type="text" style=
            "height:40px; width:760px; " value="21,52,52,21,62,80,70,61,12,21,52,52,21,62,82,70,61,13,21,52,52,21,62,80,70,61,12"/>
      <br/> Period:<input id="udm" type="text" value="7"/><br/>
	   Smoothing:<input id="udn" type="text" value="5"/>
        <div>
            <input type="button" value="U/D ratio" onclick="calUD()" />
        </div>
	
        <div id="udOutData">
        </div>
        <p>-------------------</p>
        <div>
            input(,)<input id="smaInputData" type="text" style=
            "height:40px; width:760px; " />
        </div>

        <div>
            Period:<input id="smaP" type="text" /> <input type=
            "button" value="SMA" onclick="calSMA()" />
        </div>

        <div id="smaOutData">
        </div>

        <p>-------------------</p>

        <div>
            input(,)<input id="emaInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            Period:<input id="emaP" type="text" /> <input type=
            "button" value="EMA" onclick="calEMA()" />
        </div>

        <div id="emaOutData">
        </div>

        <p>-------------------</p>

        <div>
            input(,)<input id="bbandsInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            Period:<input id="bbandsP" type="text" /> 

            <div>
                Dev:<input id="dev" type="text" />
            </div>
            <input type="button" value="BBands" onclick=
            "calBBands()" />
        </div>

        <div id="bbandsOutData">
        </div>

        <p>-------------------</p>

        <div>
            input(,)<input id="macdInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            slow Period:<input id="macdsp" type="text" /> 

            <div>
                fast Period:<input id="macdfp" type="text" />
            </div>

            <div>
                Signal Period:<input id="macdslp" type="text" />
            </div>
            <input type="button" value="MACD" onclick=
            "calMACD()" />
        </div>

        <div id="macdOutData">
        </div>

        <p>-------------------</p>

        <div>
            input(,)<input id="rocInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            Period:<input id="rocP" type="text" /> <input type=
            "button" value="ROC" onclick="calRoc()" />
        </div>

        <div id="rocOutData">
        </div>

        <p>-------------------</p>

        <div>
            input([,,,]|[,,,])<input id="rsiInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            Period:<input id="rsiP" type="text" /> <input type=
            "button" value="RSI" onclick="calRSI()" />
        </div>

        <div id="rsiOutData">
        </div>
		<p>-------------------</p>

        <div>
            input([,,,]|[,,,])<input id="willInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            Period:<input id="willP" type="text" /> <input type=
            "button" value="Williams %R" onclick="calWillR()" />
        </div>
		  <div id="willOutData">
        </div>
<p>-------------------</p>

        <div>
            input([,,,]|[,,,])<input id="fsInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            K%:<input id="fk" type="text" />
			D%:<input id="fd" type="text" />
			 <input type= "button" value="Fast Stochastic" onclick="calFS()" />
        </div>
		  <div id="fsOutData">
        </div>
<p>-------------------</p>

        <div>
            input([,,,]|[,,,])<input id="ssInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            %K:<input id="sk" type="text" />
			%D:<input id="sd" type="text" /> 
			 <input type=
            "button" value="Slow Stochastic" onclick="calSS()" />
        </div>

        <div id="ssOutData">
        </div>
		 <p>-------------------</p>

        <div>
            input([,,,]|[,,,])<input id="psarInputData" type="text" style=
            "height:40px; width:760px" />
        </div>

        <div>
            Period:<input id="psarP" type="text" /> 
			Period:<input id="psarMP" type="text" /><input type=
            "button" value="PSAR" onclick="calPSAR()" />
        </div>

        <div id="psarOutData">
        </div>
<script type="text/javascript">
var cal = new indicatorCalculation();
function calKeltner() {
 document.getElementById("keltnerOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("keltnerInputData").value;
 var ema =document.getElementById("kemaP").value;
 var time = document.getElementById("ktimesP").value;
 var atr = document.getElementById("katrP").value;
 var dataTemp = eval(dataStr);
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculateKeltner(data,0,parseInt(ema),parseInt(time),parseInt(atr));
    var s1="",s2="",s3="";
  for(var j = 0; j < outData[0].length; j++) {
	s1 +=outData[0][j][1].toFixed(4)+",";
  }
  for(var j = 0; j < outData[1].length; j++) {
	s2 +=outData[1][j][1].toFixed(4)+",";
  }
  for(var j = 0; j < outData[2].length; j++) {
	s3 +=outData[2][j][1].toFixed(4)+",";
  }
  document.getElementById("keltnerOutData").innerHTML = s1+"<br/>"+s2+"<br/>"+s3;
}
function calAtr() {
 document.getElementById("atrOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("atrInputData").value;
 var dataTemp = eval(dataStr);
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculateAtr(data,0);
  
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+"   ";
  }
  document.getElementById("atrOutData").innerHTML = str;
}
function calforceIndex() {
 document.getElementById("forceIndexOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("forceIndexInputData").value;
 var forceIndexStr = document.getElementById("forceIndexVolume").value;
 var dataTemp =dataStr.split(",");
 var dataforceIndex = forceIndexStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,parseInt(dataTemp[i],10),i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataforceIndex[i],10)];
  }
  var outData = cal.calculateForceIndex(data,dataInput,0,parseInt(document.getElementById("forceIndexP").value));
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("forceIndexOutData").innerHTML = str;
}
function calVolatility() {
 document.getElementById("volatilityOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("volatilityInputData").value;
 var perStr = document.getElementById("volatilityP").value;
 var periodStr = document.getElementById("volatilityAgo").value;
 var dataTemp = eval(dataStr);
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
   var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculateVolatility(data,0,parseInt(periodStr,10),parseInt(perStr,10));
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+"   ";
  }
  document.getElementById("volatilityOutData").innerHTML = str;
}
function calMess() {
 document.getElementById("messOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("messInputData").value;
 var dataTemp = eval(dataStr);
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculateMess(data,0);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+"   ";
  }
  document.getElementById("messOutData").innerHTML = str;
}
function calAccDis() {
 document.getElementById("accdisOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("accdisInputData").value;
 var volStr = document.getElementById("accdisVolume").value;
 var dataTemp = eval(dataStr);
 var dataVol = volStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataVol[i],10)];
  }
  var outData = cal.calculateAccDis(data,dataInput,0);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+"   ";
  }
  document.getElementById("accdisOutData").innerHTML = str;
}
function calWMA() {
 document.getElementById("wmapOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("wmapInputData").value;
 var period = document.getElementById("wmaP").value;
 var dataTemp = dataStr.split(",");;
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,parseInt(dataTemp[i]),i*10];
    data[i] = dp;
  }
  var outData = cal.calculateWMA(data,0,parseInt(period));
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+"   ";
  }
  document.getElementById("wmapOutData").innerHTML = str;
}
function calVOLP() {
 document.getElementById("volpOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("volpInputData").value;
 var volStr = document.getElementById("volpVolume").value;
 var dataTemp = eval(dataStr);
 var dataVol = volStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataVol[i],10)];
  }
  var outData = cal.calculateVolp(data,dataInput,0,0);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][0].toFixed(4)+"   "+outData[j][1].toFixed(4)+"  "+outData[j][2].toFixed(4)+"<br/>";
  }
  document.getElementById("volpOutData").innerHTML = str;
}
function calDMI() {
 document.getElementById("dmiOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("dmiInputData").value;
 var period = 0;
 var dataTemp = eval(dataStr);
 var dataInput = [];
 if (isNaN(period) && dataTemp.length < period) return;
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculateDmi(data,0,period);
  var str="";
 for(var j = 0; j < outData[0].length; j++) {
    str+=outData[0][j][1]+", ";
  }
  str +="<br/><br/>";
   for(var j = 0; j < outData[1].length; j++) {
    str+=outData[1][j][1]+", ";
  }
  str +="<br/><br/>";
   for(var j = 0; j < outData[1].length; j++) {
    str+=outData[2][j][1]+", ";
  }
  document.getElementById("dmiOutData").innerHTML = str;
}
function calPC() {
 document.getElementById("pcOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("pcInputData").value;
 var periodStr = document.getElementById("pcP").value;
  var dataTemp = eval(dataStr);
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculatePc(data,0,parseInt(periodStr,10));
  var str="";
  for(var j = 0; j < outData[0].length; j++) {
    str+=outData[0][j][1]+", ";
  }
  str +="<br/><br/>";
   for(var j = 0; j < outData[1].length; j++) {
    str+=outData[1][j][1]+", ";
  }
  document.getElementById("pcOutData").innerHTML = str;
}
function calMAEN() {
 document.getElementById("maenOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("maenInputData").value;
 var perStr = document.getElementById("maenPer").value;
 var periodStr = document.getElementById("momP").value;
 var dataTemp =dataStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,parseInt(dataTemp[i],10),i*10];
    data[i] = dp;
  }
  var outData = cal.calculateMaen(data,0,parseInt(periodStr,10),parseInt(perStr,10));
  var str="";
  for(var j = 0; j < outData[0].length; j++) {
    str+=outData[0][j][1]+", ";
  }
  str +="<br/><br/>";
   for(var j = 0; j < outData[1].length; j++) {
    str+=outData[1][j][1]+", ";
  }
  document.getElementById("maenOutData").innerHTML = str;
}
function calVOL() {
 document.getElementById("volOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("volInputData").value;
 var volStr = document.getElementById("volVolume").value;
  var periodStr = document.getElementById("volP").value;
 var dataTemp =dataStr.split(",");
 var dataVol = volStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,parseInt(dataTemp[i],10),i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataVol[i],10)];
  }
  var outData = cal.calculateVol(data,dataInput,0,parseInt(periodStr,10));
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("volOutData").innerHTML = str;
}
function calULT() {
 document.getElementById("ultOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("ultInputData").value;
 var period = 0;
 var dataTemp = eval(dataStr);
 var dataInput = [];
 if (isNaN(period) && dataTemp.length < period) return;
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
  }
  var outData = cal.calculateUlt(data,0,period);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("ultOutData").innerHTML = str;
}
function calMOM() {
 document.getElementById("momOutData").innerHTML = "";
 var data = [];
 var periodStr = document.getElementById("momP").value;
 var dataStr = document.getElementById("momInputData").value;
 var period = parseInt(periodStr,10);
 var inputData = dataStr.split(",");
 if (isNaN(period) && inputData.length < period) return;
  for (var i = 0;i< inputData.length;i++) {
    var dp = [i,parseFloat(inputData[i]),i*10];
    data[i] = dp;
  }
  var outData = cal.calculateMom(data,0,period);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("momOutData").innerHTML = str;
}
function calMFI() {
 document.getElementById("mfiOutData").innerHTML = "";
 var data = [];
 var periodStr = document.getElementById("mfiP").value;
 var dataStr = document.getElementById("mfiInputData").value;
 var volStr = document.getElementById("mfiVolume").value;
 var period = parseInt(periodStr,10);
 var dataTemp = eval(dataStr);
 var dataVol = volStr.split(",");
 var dataInput = [];
 if (isNaN(period) && dataTemp.length < period) return;
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
	dataInput[i]=[i,dataVol[i]];
  }
  var outData = cal.calculateMfi(data,dataInput,0,period);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("mfiOutData").innerHTML = str;
}
function calVACC() {
 document.getElementById("vaccOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("vaccInputData").value;
 var volStr = document.getElementById("vaccVolume").value;
 var dataTemp = eval(dataStr);
 var dataVol = volStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,dataTemp[i][0],dataTemp[i][1],dataTemp[i][2],i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataVol[i],10)];
  }
  var outData = cal.calculateVacc(data,dataInput,0,0);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("vaccOutData").innerHTML = str;
}
function calOBV() {
 document.getElementById("obvOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("obvInputData").value;
 var volStr = document.getElementById("obvVolume").value;
 var dataTemp =dataStr.split(",");
 var dataVol = volStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,parseInt(dataTemp[i],10),i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataVol[i],10)];
  }
  var outData = cal.calculateObv(data,dataInput,0,0);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("obvOutData").innerHTML = str;
}
function calUD() {
 document.getElementById("udOutData").innerHTML = "";
 var data = [];
 var dataStr = document.getElementById("udInputData").value;
 var volStr = document.getElementById("udVolume").value;
 var udm =parseInt(document.getElementById("udm").value);
 var udn = parseInt(document.getElementById("udn").value);
 var dataTemp =eval(dataStr);
 var dataVol = volStr.split(",");
 var dataInput = [];
  for (var i = 0;i< dataTemp.length;i++) {
    var dp = [i,parseInt(dataTemp[i],10),i*10];
    data[i] = dp;
	dataInput[i]=[i,parseInt(dataVol[i],10)];
  }
  var outData = cal.calculateUd(data,dataInput,0,udm,udn);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("udOutData").innerHTML = str;
}
function calSMA() {
 document.getElementById("smaOutData").innerHTML = "";
 var data = [];
 var periodStr = document.getElementById("smaP").value;
 var dataStr = document.getElementById("smaInputData").value;
 var period = parseInt(periodStr,10);
 var inputData = dataStr.split(",");
 if (isNaN(period) && inputData.length < period) return;
  for (var i = 0;i< inputData.length;i++) {
    var dp = [i,parseFloat(inputData[i]),i*10];
    data[i] = dp;
  }
  var outData = cal.calculateSma(data,0,period);
  var str="";
  for(var j = 0; j < outData.length; j++) {
    str+=outData[j][1].toFixed(4)+", ";
  }
  document.getElementById("smaOutData").innerHTML = str;
}
function calEMA() {
    document.getElementById("emaOutData").innerHTML = "";
    var data = [];
    var periodStr = document.getElementById("emaP").value;
    var dataStr = document.getElementById("emaInputData").value;
    var period = parseInt(periodStr,10);
    var inputData = dataStr.split(",");
    //if (isNaN(period) && inputData.length < period) return;
    for (var i = 0;i< inputData.length;i++) {
        var dp = [i,parseFloat(inputData[i]),i*10];
        data[i] = dp;
    }
    var outData = cal.calculateEma(data,0,period);
    var str="";
    for(var j = 0; j < outData.length; j++) {
        str+=outData[j][1].toFixed(4)+", ";
    }
    document.getElementById("emaOutData").innerHTML = str;
}
function calBBands() {
    document.getElementById("bbandsOutData").innerHTML = "";
    var data = [];
    var periodStr = document.getElementById("bbandsP").value;
    var devStr = document.getElementById("dev").value;
    var dataStr = document.getElementById("bbandsInputData").value;
    var period = parseInt(periodStr,10);
    var dev = parseInt(devStr,10);
    var inputData = dataStr.split(",");
    if (isNaN(period) && isNaN(dev) && inputData.length < period) return;
    for (var i = 0; i< inputData.length;i++) {
        var dp = [i,parseFloat(inputData[i]),i*10];
        data[i] = dp;
    }
    var outData = cal.calculateBBands(data,0,period,dev);
    var str="";
    for(var j = 0; j < outData.length; j++) {
        str+= j==0? "U:":"L:";
        for(var k = 0; k < outData[j].length; k++) {
            str+=outData[j][k][1].toFixed(4)+", ";
        }
        str += "<br>";
    }
    document.getElementById("bbandsOutData").innerHTML = str;
}
function calMACD() {
document.getElementById("bbandsOutData").innerHTML = "";
    var data = [];
    var slowperiod = parseInt(document.getElementById("macdsp").value,10);
    var fastperiod = parseInt(document.getElementById("macdfp").value,10);
    var signalperiod = parseInt(document.getElementById("macdslp").value,10);
    var dataStr = document.getElementById("macdInputData").value;
    var inputData = dataStr.split(",");
    if (isNaN(slowperiod) ||isNaN(fastperiod) ||isNaN(signalperiod)) return;
    for (var i = 0; i< inputData.length;i++) {
        var dp = [i,parseFloat(inputData[i]),i*10];
        data[i] = dp;
    }
    var outData = cal.calculateMACD(data,0,slowperiod,fastperiod,signalperiod);
    var macdStr = "MACD("+slowperiod+","+fastperiod+"):";
    var str="";
    var em = "EMA("+signalperiod+"):";
    for(var j = 0; j < outData.length; j++) {
        str+= j==0? macdStr:(j==1?em:"Divergence:");
        for(var k = 0; k < outData[j].length; k++) {
            str+=outData[j][k][1].toFixed(4)+", ";
        }
        str += "<br>";
    }
    document.getElementById("macdOutData").innerHTML = str;
    
}
function calRoc(){
    document.getElementById("rocOutData").innerHTML = "";
    var data = [];
    var p = parseInt(document.getElementById("rocP").value,10);
    var dataStr = document.getElementById("rocInputData").value;
    var inputData = dataStr.split(",");
    if (isNaN(p)) return;
    for (var i = 0; i< inputData.length;i++) {
        var dp = [i,parseFloat(inputData[i]),i*10];
        data[i] = dp;
    }
    var outData = cal.calculateROC(data,0,p);
    var str = "ROC("+p+"):";
    for(var k = 0; k < outData.length; k++) {
            str+=outData[k][1].toFixed(4)+", ";
        }
    str += "<br>";
    
    document.getElementById("rocOutData").innerHTML = str;
}
function calRSI(){
    document.getElementById("rsiOutData").innerHTML = "";
    var data = [];
    var p = parseInt(document.getElementById("rsiP").value,10);


    var dataStr = document.getElementById("rsiInputData").value;
    var inputData = dataStr.split(",");
    if (isNaN(p) ) return;
    for (var i = 0; i< inputData.length;i++) {
        var dp = [i,parseFloat(inputData[i]),i*10];
        data[i] = dp;
    }
    var outData = cal.calculateRSI(data,0,p);
    var str = "RSI("+p+"):";
    for(var k = 0; k < outData.length; k++) {
            str+=outData[k][1].toFixed(4)+", ";
        }
    str += "<br>";
    
    document.getElementById("rsiOutData").innerHTML = str;
}
function calWillR(){
    document.getElementById("willOutData").innerHTML = "";
    var data = [];
    var p = parseInt(document.getElementById("willP").value,10);


    var dataStr = document.getElementById("willInputData").value;
    var inputData = dataStr.split("|");
    if (isNaN(p) ) return;
    for (var i = 0; i< inputData.length;i++) {
        var d = eval(inputData[i]);
        var dp = [i,d[0],d[1],d[2],d[3],i*10];
        data[i] = dp;
    }
    var outData = cal.calculateWillR(data,0,p);
    var str = "Williams %R("+p+"):";
    for(var k = 0; k < outData.length; k++) {
            str+=outData[k][1].toFixed(4)+", ";
        }
    str += "<br>";
    
    document.getElementById("willOutData").innerHTML = str;
}
function calFS(){
	document.getElementById("fsOutData").innerHTML = "";
    var data = [];
    var pk = parseInt(document.getElementById("fk").value,10);
	var pd = parseInt(document.getElementById("fd").value,10);

    var dataStr = document.getElementById("fsInputData").value;
    var inputData = dataStr.split("|");
    if (isNaN(pk)||isNaN(pd) ) return;
    for (var i = 0; i< inputData.length;i++) {
        var d = eval(inputData[i]);
        var dp = [i,d[0],d[1],d[2],d[3],i*10];
        data[i] = dp;
    }
    var outData = cal.calculateFastStochastic(data,0,pk,pd);
    var str = "Fast Stochastic("+pk+","+pd+"):";
    for(var j = 0; j < outData.length; j++) {
        str+= j==0? "%K: ":"%D:";
        for(var k = 0; k < outData[j].length; k++) {
            str+=outData[j][k][1].toFixed(4)+", ";
        }
        str += "<br>";
    }
    
    document.getElementById("fsOutData").innerHTML = str;
}
function calSS(){
	document.getElementById("ssOutData").innerHTML = "";
    var data = [];
    var pk = parseInt(document.getElementById("sk").value,10);
	var pd = parseInt(document.getElementById("sd").value,10);

    var dataStr = document.getElementById("ssInputData").value;
    var inputData = dataStr.split("|");
    if (isNaN(pk)||isNaN(pd) ) return;
    for (var i = 0; i< inputData.length;i++) {
        var d = eval(inputData[i]);
        var dp = [i,d[0],d[1],d[2],d[3],i*10];
        data[i] = dp;
    }
    var outData = cal.calculateSlowStochastic(data,0,pk,pd);
    var str = "Slow Stochastic("+pk+","+pd+"):";
    for(var j = 0; j < outData.length; j++) {
        str+= j==0? "%K: ":"%D: ";
        for(var k = 0; k < outData[j].length; k++) {
            str+=outData[j][k][1].toFixed(4)+", ";
        }
        str += "<br>";
    }
    str += "<br>";
    
    document.getElementById("ssOutData").innerHTML = str;
}
function calPSAR(){
	document.getElementById("fsOutData").innerHTML = "";
    var data = [];
    var p = parseFloat(document.getElementById("psarP").value);
	var mp = parseFloat(document.getElementById("psarMP").value);
	if(isNaN(p)|| isNaN(mp)){
		return;
	}
	var dataStr = document.getElementById("psarInputData").value;
    var inputData = dataStr.split("|");
	for (var i = 0; i< inputData.length;i++) {
        var d = eval(inputData[i]);
        var dp = [i,d[0],d[1],d[2],d[3],i*10];
        data[i] = dp;
    }
    var outData = cal.calculatePSAR(data,0,p,mp);
    var str = "PSAR("+p+"):";
    for(var k = 0; k < outData.length; k++) {
            str+=outData[k][1].toFixed(4)+", ";
        }
    str += "<br>";
    
    document.getElementById("psarOutData").innerHTML = str;
}
</script>
    </body>
</html>

